package de.hska.master.algo.gui;

import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

import javax.swing.JFrame;

import de.hska.master.algo.Controller;
import de.hska.master.model.Model;

public class Viewer extends JFrame {

	private static final long serialVersionUID = 6896524458148356548L;

	public class MyMouseMotionListener extends MouseMotionAdapter {

		private Viewer v;

		public MyMouseMotionListener(Viewer v) {
			this.v = v;
		}

		@Override
		public void mouseMoved(MouseEvent arg0) {
			Point p = arg0.getPoint();
			lastMousePosition = p;
			v.repaint();
		}
	}

	private Point lastMousePosition = null;

	private Model model = null;

	public Viewer(Model model) {
		this.model = model;
		this.addMouseMotionListener(new MyMouseMotionListener(this));
	}

	@Override
	public void paint(final Graphics g) {
		super.paint(g);

		drawConvexHull(g);
		drawPoints(g);
		drawMousePosition(g);
	}

	final int widthArcAroundPoint = 20;
	final int heightArcAroundPoint = 20;

	final int widthFilledMiniArcAroundPoint = widthArcAroundPoint / 2;
	final int heightFilledMiniArcAroundPoint = heightArcAroundPoint / 2;

	private void drawPoints(Graphics g) {
		for (Point point : convertToAWTPoints(model.getPoints())) {
			int newY = Controller.VIEWER_HEIGHT - point.y;
			int x = point.x - widthArcAroundPoint / 2;
			int y = newY - heightArcAroundPoint / 2;
			g.drawArc(x, y, widthArcAroundPoint, heightArcAroundPoint, 0, 360);

			x = point.x - widthFilledMiniArcAroundPoint / 2;
			y = newY - heightFilledMiniArcAroundPoint / 2;

			g.fillArc(x, y, widthFilledMiniArcAroundPoint,
					heightFilledMiniArcAroundPoint, 0, 360);
		}
	}

	private void drawConvexHull(Graphics g) {
		Point[] convexHull = convertToAWTPoints(model.getConvexHull());

		final int nPoints = convexHull.length;
		int[] xPoints = new int[nPoints];
		int[] yPoints = new int[nPoints];

		for (int i = 0; i < nPoints; ++i) {
			int xComponent = convexHull[i].x;
			int yComponent = convexHull[i].y;
			xPoints[i] = xComponent;
			yPoints[i] = Controller.VIEWER_HEIGHT - yComponent;
		}

		g.drawPolygon(xPoints, yPoints, nPoints);
	}

	private Point[] convertToAWTPoints(de.hska.master.model.Point[] points) {
		Point[] awtPoints = new Point[points.length];

		for (int i = 0; i < points.length; i++) {
			Point point = new Point();
			point.setLocation(points[i].getX(), points[i].getY());
			awtPoints[i] = point;
		}
		return awtPoints;
	}

	private void drawMousePosition(Graphics g) {
		if (lastMousePosition == null)
			return;

		int mousePosX = lastMousePosition.x;
		int mousePosY = lastMousePosition.y;
		int mousePosYCorrected = Controller.VIEWER_HEIGHT - lastMousePosition.y;

		g.drawString("[x=" + mousePosX + "|y=" + mousePosYCorrected + "]", mousePosX,
				mousePosY);
	}
}